package main

// This file is turned into include.go by template2include.go automatically
// during build.
import (
	"os"
	"fmt"
	"runtime"
	"strconv"
	"strings"
	"path/filepath"
)

type _Ðβご_shift_item_ struct {
	file string
	line int
}

var G_Ðβご_package_name_ = "SED IS MY FRIEND"

var V_Ðβご_shift_map_ = map[string]_Ðβご_shift_item_{
	"???": _Ðβご_shift_item_{"<unknown>", -1},
	//HOLE - do not remove this comment or template2include.sh will break
}

func f_Ðβご_contract_violation_(dfrd bool, con, fun string, rcvr interface{}, parms, rets []interface{}) {
	skip := 2
	if dfrd {
		skip++
	}

	//get caller info
	cpkg, name := "", ""
	pc, file, line, ok := runtime.Caller(skip)
	if ok {
		if f := runtime.FuncForPC(pc); f != nil {
			if ss := strings.SplitN(f.Name(), ".", 2); len(ss) == 2 {
				cpkg, name = ss[0], ss[1]
			} else {
				name = ss[0]
			}
		}
	}
	if name == "" || name == "." {
		name = "???"
	}
	caller := ""
	if cpkg == G_Ðβご_package_name_ {
		if s, ok := V_Ðβご_shift_map_[name]; ok {
			file, line = s.file, s.line
		}
		caller = fmt.Sprintf("%s:%d:%s", filepath.Base(file), line, name)
	} else if cpkg != "" {
		caller = fmt.Sprintf("%s.%s", cpkg, name)
	} else {
		caller = name
	}

	//get callee info (in shift map by construction)
	s := V_Ðβご_shift_map_[fun]
	callee := fmt.Sprintf("%s:%d:%s", s.file, s.line, fun)

	//reformat contract (can't use backtick strings here)
	con, _ = strconv.Unquote("\"" + con + "\"")

	dirn := "entry into"
	if dfrd {
		dirn = "exit from"
	}

	//output
	acc := []string{"\n"}
	push := func(s string) {
		acc = append(acc, s)
	}
	pushln := func(s ...interface{}) {
		push(fmt.Sprintln(s...))
	}
	pushf := func(s string, is ...interface{}) {
		push(fmt.Sprintf(s, is...))
	}
	pushf("%s violated «%s» on %s %s with:\n", caller, con, dirn, callee)
	if rcvr != nil {
		push("Reciever: ")
		pushln(rcvr)
	}
	if len(parms) > 0 {
		push("Parameters: ")
		pushln(parms...)
	}
	if dfrd && len(rets) > 0 {
		push("Returns: ")
		pushln(rets...)
	}

	fmt.Print(strings.Join(acc, ""))
	os.Exit(127)
}
